{
 "cells": [
  {
   "cell_type": "markdown",
   "source": [
    "工具输出结果传递给智能体\n",
    "![](./image/tool3.png)"
   ],
   "metadata": {
    "collapsed": false
   },
   "id": "d2010e4c85b7a51"
  },
  {
   "cell_type": "code",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[{'name': 'multiply', 'args': {'a': 3, 'b': 12}, 'id': 'call_239f79ba43b8463083d95c', 'type': 'tool_call'}]\n"
     ]
    }
   ],
   "source": [
    "import os\n",
    "\n",
    "from dotenv import load_dotenv\n",
    "from langchain_core.messages import HumanMessage\n",
    "from langchain_core.tools import tool\n",
    "from langchain_openai import ChatOpenAI\n",
    "\n",
    "load_dotenv()\n",
    "llm = ChatOpenAI(\n",
    "    # 若没有配置环境变量，请用百炼API Key将下行替换为：api_key=\"sk-xxx\",\n",
    "    openai_api_key=os.getenv(\"DASHSCOPE_API_KEY\"),\n",
    "    openai_api_base=\"https://dashscope.aliyuncs.com/compatible-mode/v1\",\n",
    "    model_name=\"qwen-max\",\n",
    "    max_retries=0,\n",
    ")\n",
    "\n",
    "\n",
    "@tool\n",
    "def add(a: int, b: int) -> int:\n",
    "    \"\"\"Adds a and b.\"\"\"\n",
    "    return a + b\n",
    "\n",
    "\n",
    "@tool\n",
    "def multiply(a: int, b: int) -> int:\n",
    "    \"\"\"Multiplies a and b.\"\"\"\n",
    "    return a * b\n",
    "\n",
    "\n",
    "tools = [add, multiply]\n",
    "# 绑定tools到llm\n",
    "llm_with_tools = llm.bind_tools(tools)\n",
    "\n",
    "query = \"What is 3 * 12? Also, what is 11 + 49?\"\n",
    "messages = [HumanMessage(query)]\n",
    "\n",
    "ai_msg = llm_with_tools.invoke(messages)\n",
    "print(ai_msg.tool_calls)\n",
    "messages.append(ai_msg)"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2024-10-31T05:18:29.771176Z",
     "start_time": "2024-10-31T05:18:27.527604Z"
    }
   },
   "id": "f3f190dccf8ff34d",
   "execution_count": 3
  },
  {
   "cell_type": "markdown",
   "source": [
    "接下来，我们将使用模型填充的args来调用工具函数！\n",
    "\n",
    "方便地是，如果我们使用ToolCall调用LangChain工具，将自动返回一个ToolMessage，该消息可以反馈给模型："
   ],
   "metadata": {
    "collapsed": false
   },
   "id": "705b7b96b67b66db"
  },
  {
   "cell_type": "code",
   "outputs": [
    {
     "data": {
      "text/plain": "[HumanMessage(content='What is 3 * 12? Also, what is 11 + 49?', additional_kwargs={}, response_metadata={}),\n AIMessage(content='', additional_kwargs={'tool_calls': [{'id': 'call_239f79ba43b8463083d95c', 'function': {'arguments': '{\"a\": 3, \"b\": 12}', 'name': 'multiply'}, 'type': 'function', 'index': 0}], 'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 23, 'prompt_tokens': 251, 'total_tokens': 274, 'completion_tokens_details': None, 'prompt_tokens_details': None}, 'model_name': 'qwen-max', 'system_fingerprint': None, 'finish_reason': 'tool_calls', 'logprobs': None}, id='run-e9a817d9-7c7d-41a3-9bab-e966548ce111-0', tool_calls=[{'name': 'multiply', 'args': {'a': 3, 'b': 12}, 'id': 'call_239f79ba43b8463083d95c', 'type': 'tool_call'}], usage_metadata={'input_tokens': 251, 'output_tokens': 23, 'total_tokens': 274, 'input_token_details': {}, 'output_token_details': {}}),\n ToolMessage(content='36', name='multiply', tool_call_id='call_239f79ba43b8463083d95c')]"
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "for tool_call in ai_msg.tool_calls:\n",
    "    selected_tool = {\"add\": add, \"multiply\": multiply}[tool_call[\"name\"].lower()]\n",
    "    tool_msg = selected_tool.invoke(tool_call)\n",
    "    messages.append(tool_msg)\n",
    "\n",
    "messages"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2024-10-31T05:20:03.571120Z",
     "start_time": "2024-10-31T05:20:03.556873Z"
    }
   },
   "id": "394d0ef2d5a12be4",
   "execution_count": 4
  },
  {
   "cell_type": "markdown",
   "source": [
    "最后，我们将使用工具结果调用模型。模型将使用这些信息为原始查询生成最终答案："
   ],
   "metadata": {
    "collapsed": false
   },
   "id": "300c3e74cd90e3eb"
  },
  {
   "cell_type": "code",
   "outputs": [
    {
     "data": {
      "text/plain": "AIMessage(content='', additional_kwargs={'tool_calls': [{'id': 'call_cbc041819b114d53a8a86d', 'function': {'arguments': '{\"a\": 11, \"b\": 49}', 'name': 'add'}, 'type': 'function', 'index': 0}], 'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 26, 'prompt_tokens': 285, 'total_tokens': 311, 'completion_tokens_details': None, 'prompt_tokens_details': None}, 'model_name': 'qwen-max', 'system_fingerprint': None, 'finish_reason': 'tool_calls', 'logprobs': None}, id='run-ca9b6881-dd6c-4c43-a43e-62495d9d381e-0', tool_calls=[{'name': 'add', 'args': {'a': 11, 'b': 49}, 'id': 'call_cbc041819b114d53a8a86d', 'type': 'tool_call'}], usage_metadata={'input_tokens': 285, 'output_tokens': 26, 'total_tokens': 311, 'input_token_details': {}, 'output_token_details': {}})"
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "llm_with_tools.invoke(messages)\n"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2024-10-31T05:23:10.221295Z",
     "start_time": "2024-10-31T05:23:06.434857Z"
    }
   },
   "id": "1dbed0befeddc825",
   "execution_count": 5
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
